package com.taobao.tbapi;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.taobao.api.domain.Item;
import com.taobao.api.request.ItemGetRequest;
import com.taobao.api.request.ItemsInventoryGetRequest;
import com.taobao.api.request.ItemsOnsaleGetRequest;
import com.taobao.api.response.ItemGetResponse;
import com.taobao.api.response.ItemsInventoryGetResponse;
import com.taobao.api.response.ItemsOnsaleGetResponse;

public class ItemApis {

  public final static Logger log               = LoggerFactory.getLogger(ItemApis.class);
  public static final String FIELDS            = "has_showcase, is_virtual, seller_cids,detail_url,approve_status,num_iid,title,nick,cid,pic_url,num,price,list_time,delist_time,outer_id";
  public static final String FIELDS_WITH_PROPS = "has_showcase, is_virtual, props, props_name,property_alias, seller_cids,detail_url,approve_status,num_iid,title,nick,cid,pic_url,num,price,list_time,delist_time,outer_id";

  public static final String FIELDS_WITH_DESC  = "has_showcase,item_weight,item_size,num,item_img, is_virtual, props,desc,skus,sku, props_name,property_alias, seller_cids,detail_url,approve_status,num_iid,title,nick,cid,pic_url,num,price,list_time,delist_time,outer_id,prop_imgs,prop_img";

  public static final String SIMPLE_FIELDS     = "num_iid, title, pic_url, price";

  public static List<Long> extractNumIidFromItem(List<Item> itemList) {
    if (CollectionUtils.isEmpty(itemList)) {
      return null;
    }

    List<Long> numIidList = new ArrayList<Long>();

    for (Item item : itemList) {
      numIidList.add(item.getNumIid());
    }

    return numIidList;
  }

  public static class ItemsOnsale extends TBApi<ItemsOnsaleGetRequest, ItemsOnsaleGetResponse, List<Item>> {
    public Long       startModified;
    public Long       endModified;
    public boolean    hasInit = false;
    public long       pageNo  = 1;
    public List<Item> resList;

    public ItemsOnsale(String sid, Long startModified, Long endModified) {
      super(sid);
      this.startModified = startModified;
      this.endModified = endModified;
      this.resList = new ArrayList<Item>();
    }

    @Override
    public ItemsOnsaleGetRequest prepareRequest() {
      ItemsOnsaleGetRequest req = new ItemsOnsaleGetRequest();

      req.setPageNo(pageNo++);
      req.setFields(FIELDS);
      req.setPageSize(ApiConfigs.PageSize.ITEM_PAGE_SIZE);

      if ((startModified != null) && (startModified > 0)) {
        req.setStartModified(new Date(startModified));
      }

      if ((endModified != null) && (endModified > 0)) {
        req.setEndModified(new Date(endModified));
      }

      return req;
    }

    @Override
    public List<Item> validResponse(ItemsOnsaleGetResponse resp) {
      if (!hasInit) {
        long totalResult = resp.getTotalResults();

        this.iteratorTime = (int) CommonUtils.calculatePageCount(totalResult, ApiConfigs.PageSize.ITEM_PAGE_SIZE) - 1;
        this.hasInit = true;
      }

      return resp.getItems();
    }

    @Override
    public List<Item> applyResult(List<Item> res) {
      if (res == null) {
        return resList;
      }

      resList.addAll(res);

      return resList;
    }
  }

  public static class ItemsOnsaleTotalNum extends TBApi<ItemsOnsaleGetRequest, ItemsOnsaleGetResponse, Long> {
    public Long startModified;
    public Long endModified;

    public ItemsOnsaleTotalNum(String sid, Long startModified, Long endModified) {
      super(sid);
      this.startModified = startModified;
      this.endModified = endModified;
    }

    @Override
    public ItemsOnsaleGetRequest prepareRequest() {
      ItemsOnsaleGetRequest req = new ItemsOnsaleGetRequest();

      req.setPageNo(1L);
      req.setFields("num_iid");
      req.setPageSize(1L);

      if ((startModified != null) && (startModified > 0)) {
        req.setStartModified(new Date(startModified));
      }

      if ((endModified != null) && (endModified > 0)) {
        req.setEndModified(new Date(endModified));
      }

      return req;
    }

    @Override
    public Long validResponse(ItemsOnsaleGetResponse resp) {
      return resp.getTotalResults();
    }

    @Override
    public Long applyResult(Long res) {
      return res;
    }
  }

  public static class ItemsOnsalePage extends TBApi<ItemsOnsaleGetRequest, ItemsOnsaleGetResponse, List<Item>> {
    public String sid;
    public Long   startModified;
    public Long   endModified;
    public long   pageNo;
    public String field;

    public ItemsOnsalePage(String sid, Long startModified, Long endModified, Long pageNo, String field) {
      super(sid);
      this.startModified = startModified;
      this.endModified = endModified;
      this.pageNo = pageNo;
      this.field = field;
    }

    @Override
    public ItemsOnsaleGetRequest prepareRequest() {
      ItemsOnsaleGetRequest req = new ItemsOnsaleGetRequest();

      req.setPageNo(pageNo);
      req.setFields(field);
      req.setPageSize(ApiConfigs.PageSize.ITEM_PAGE_SIZE);

      if ((startModified != null) && (startModified > 0)) {
        req.setStartModified(new Date(startModified));
      }

      if ((endModified != null) && (endModified > 0)) {
        req.setEndModified(new Date(endModified));
      }

      return req;
    }

    @Override
    public List<Item> validResponse(ItemsOnsaleGetResponse resp) {
      // log.error(resp.getBody());
      return resp.getItems();
    }

    @Override
    public List<Item> applyResult(List<Item> res) {
      return res;
    }
  }

  public static class ItemsInventoryTotalNum extends TBApi<ItemsInventoryGetRequest, ItemsInventoryGetResponse, Long> {
    public Long startModified;
    public Long endModified;

    public ItemsInventoryTotalNum(String sid, Long startModified, Long endModified) {
      super(sid);
      this.startModified = startModified;
      this.endModified = endModified;
    }

    @Override
    public ItemsInventoryGetRequest prepareRequest() {
      ItemsInventoryGetRequest req = new ItemsInventoryGetRequest();

      req.setPageNo(1L);
      req.setFields("num_iid");
      req.setPageSize(1L);

      if ((startModified != null) && (startModified > 0)) {
        req.setStartModified(new Date(startModified));
      }

      if ((endModified != null) && (endModified > 0)) {
        req.setEndModified(new Date(endModified));
      }

      return req;
    }

    @Override
    public Long validResponse(ItemsInventoryGetResponse resp) {
      return resp.getTotalResults();
    }

    @Override
    public Long applyResult(Long res) {
      return res;
    }
  }

  public static class ItemsInventoryPage extends TBApi<ItemsInventoryGetRequest, ItemsInventoryGetResponse, List<Item>> {
    public String sid;
    public Long   startModified;
    public Long   endModified;
    public long   pageNo;
    public String field;

    public ItemsInventoryPage(String sid, Long startModified, Long endModified, Long pageNo, String field) {
      super(sid);
      this.startModified = startModified;
      this.endModified = endModified;
      this.pageNo = pageNo;
      this.field = field;
    }

    @Override
    public ItemsInventoryGetRequest prepareRequest() {
      ItemsInventoryGetRequest req = new ItemsInventoryGetRequest();

      req.setPageNo(pageNo);
      req.setFields(field);
      req.setPageSize(ApiConfigs.PageSize.ITEM_PAGE_SIZE);

      if ((startModified != null) && (startModified > 0)) {
        req.setStartModified(new Date(startModified));
      }

      if ((endModified != null) && (endModified > 0)) {
        req.setEndModified(new Date(endModified));
      }

      return req;
    }

    @Override
    public List<Item> validResponse(ItemsInventoryGetResponse resp) {
      // log.error(resp.getBody());
      return resp.getItems();
    }

    @Override
    public List<Item> applyResult(List<Item> res) {
      return res;
    }
  }

  public static class ItemGet extends TBApi<ItemGetRequest, ItemGetResponse, Item> {
    public static int ITEM_GET_530 = 530;
    public Long       numIid;
    private boolean   useProps;

    private String    fields;

    public ItemGet(String sid, Long numIid, String fields) {
      super(sid);
      this.numIid = numIid;
      this.fields = fields;
    }

    public ItemGet(String sid, Long numIid) {
      super(sid);
      this.numIid = numIid;
      this.fields = FIELDS;
    }

    public ItemGet(String sessionKey, Long numIid2, boolean b) {
      super(sessionKey);
      this.numIid = numIid2;
      this.fields = FIELDS_WITH_PROPS;
    }

    @Override
    public ItemGetRequest prepareRequest() {
      ItemGetRequest req = new ItemGetRequest();
      req.setFields(fields);
      req.setNumIid(numIid);

      return req;
    }

    @Override
    public Item validResponse(ItemGetResponse resp) {
      return resp.getItem();
    }

    @Override
    public Item applyResult(Item res) {
      return res;
    }
  }

}
